home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gekkan Dennou Club 142
/
Gekkan Dennou Club - 2000.3 Vol. 142 (Japan).7z
/
Gekkan Dennou Club - 2000.3 Vol. 142 (Japan) (Track 1).bin
/
tools
/
pws
/
pws011.lzh
/
ServerCore.c
< prev
next >
Wrap
C/C++ Source or Header
|
2000-02-01
|
8KB
|
322 lines
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <sys/dos.h>
#include <sys/stat.h>
#include <sys/xglob.h>
#include <network.h>
#include <socket.h>
#include "PersonalWS.h"
#include "ServerCore.h"
static int sock80, temp_sock = -1;
typedef struct {
char *content_type;
char *ext_type;
} TYPE_TABLE;
TYPE_TABLE type_table[] =
{
"text/html", "HTM",
"text/html", "HTML",
"text/html", "CGI",
"text/plain", "TXT",
"text/plain", "DOC",
"image/gif", "GIF",
"image/jpeg", "JPG",
"image/jpeg", "JPEG",
"image/png", "PNG",
"image/bmp", "BMP",
"application/zip", "ZIP",
"application/x-lzh", "LZH",
"application/x-gzip", "TGZ",
"application/pdf", "PDF",
NULL, NULL
};
/* ソケットをオープンする(常駐解除に使うだけ) */
int OpenSock (char *hostname, int port)
{
int sock;
struct hostent *h;
struct sockaddr_in addr;
/* ソケットを作成する */
sock = socket (AF_INET, SOCK_STREAM, 0);
if (sock < 0) {
printf (" エラー : ソケットが作成できませんでした\n");
return (-1);
}
memset (&addr, 0, sizeof (addr)); /* 0 で埋める */
addr.sin_family = AF_INET; /* INETドメインを指定 */
addr.sin_port = htons (port); /* ポート番号 */
/* ホスト名(www.xxx.co.jp) を IP アドレス(int)に変換 */
h = gethostbyname (hostname);
if (h == NULL) {
printf (" エラー : ドメイン名がみつかりません\n");
return (-1);
}
addr.sin_addr.s_addr = *(long *) h->h_addr;
/* 相手先に接続する */
verbose_printf (" 接続中...\n");
if (connect (sock, (char *) &addr, sizeof (addr)) < 0) {
printf (" エラー : 接続に失敗しました\n");
return (-1);
}
return (sock);
}
/* 指定されたソケットからメッセージを受け取る */
int ReceiveMessage (int sock)
{
char temp_str[1024];
verbose_printf ("受信待ち...\n");
while (!socklen (sock, 0)); /* 受信待ち */
do {
recvline (sock, temp_str, 1024); /* 受信 */
verbose_printf ("受信 > %s\n", temp_str);
} while (socklen (sock, 0) > 0);
return (0);
}
/* 指定されたソケットにコマンドを送る */
int SendCommand (int sock, char *cmd)
{
verbose_printf ("送信 > %s\n", cmd);
write_s (sock, cmd, strlen (cmd)); /* 送信 */
while (!socklen (sock, 1)); /* 送信完了待ち */
ReceiveMessage (sock);
return (0);
}
/* Passive 用ソケットをオープンする */
int OpenPassiveSock (int port)
{
int sock;
struct sockaddr_in addr;
/* ソケットを作成する */
sock = socket (AF_INET, SOCK_STREAM, 0);
if (sock < 0) {
printf (" エラー : ソケットが作成できませんでした\n");
return (-1);
}
memset (&addr, 0, sizeof (addr)); /* 0 で埋める */
addr.sin_family = AF_INET; /* INETドメインを指定 */
addr.sin_port = htons (port); /* ポート番号 */
#if 0
addr.sin_addr.s_addr = INADDR_ANY;
#endif
addr.sin_addr.s_addr = htonl (0); /* INADDR_ANY:0 */
/* 相手先に接続する */
if (bind (sock, (char *) &addr, sizeof (addr)) < 0) {
printf (" エラー : 接続に失敗しました\n");
return (-1);
}
if (listen (sock, 1) < 0) {
printf (" エラー : listen でエラーが発生しました\n");
return (-1);
}
return (sock);
}
/* 接続されるのを待つ */
int AcceptSock (int sock)
{
struct sockaddr_in from;
int temp_sock;
int len = sizeof (from);
temp_sock = accept (sock, (char *) &from, &len);
if (temp_sock < 0) {
printf (" エラー : accept でエラーが発生しました\n");
return (-1);
}
return (temp_sock);
}
void CloseSock (int sock)
{
if (sock > 0)
close_s (sock);
}
int ServerInit (void)
{
if (_get_version () < 0) {
printf ("(h)inetd.x が常駐していません\n");
return (-1);
}
sock80 = OpenPassiveSock (80);
if (sock80 < 0)
return (-1);
return (0);
}
int ServerMain (void)
{
char temp_str[1024];
char method[64], url[1024], version[64];
FILE *fp;
char *content_type = "application/octet-stream"; /* 謎の拡張子の場合コレになる */
char *p = url;
char *ext = NULL;
TYPE_TABLE *t;
verbose_printf ("接続を待っています\n");
temp_sock = AcceptSock (sock80);
if (temp_sock < 0)
return (-1);
sockmode (temp_sock, SOCK_ASCII);
seteol (temp_sock, "\r\n");
verbose_printf ("接続されました\n");
while (recvline (temp_sock, temp_str, sizeof (temp_str)) < 0);
sscanf (temp_str, "%s %s %s", method, url, version);
verbose_printf (" ヘッダ > %s", temp_str);
#if 0
while (recvline (temp_sock, temp_str, sizeof (temp_str)) > 2) {
verbose_printf (" ヘッダ > %s", temp_str);
}
#endif
do {
if (recvline (temp_sock, temp_str, sizeof (temp_str)) < 0)
break;
verbose_printf (" ヘッダ > %s", temp_str);
} while (*temp_str != '\n');
/* 終了文字列のチェック */
sprintf (temp_str, "/%s", quit_str);
if (!strnicmp (url, temp_str, strlen (temp_str))) {
close_s (temp_sock);
temp_sock = -1;
return (-1); /* 常駐解除 */
}
if ((!strcmp (method, "HEAD")) || (!strcmp (method, "GET"))) {
struct stat sb;
strcpy (temp_str, base_dir);
_dellastsep (temp_str);
strcat (temp_str, url);
if ((fp = fopen (temp_str, "rb")) != NULL) {
/* ローカルファイルの拡張子から content_type を得る */
while (*p) {
if (*p++ == '.')
ext = p;
}
if (ext) {
t = type_table;
do {
if (!stricmp (ext, t->ext_type)) {
content_type = t->content_type;
break;
}
} while ((++t)->ext_type != NULL);
}
stat (temp_str, &sb);
verbose_printf (" %s を送信します\n", temp_str);
strcpy (temp_str, "HTTP/1.0 200 OK\r\n");
write_s (temp_sock, temp_str, strlen (temp_str));
sprintf (temp_str, "Content-Type: %s\r\n", content_type);
write_s (temp_sock, temp_str, strlen (temp_str));
sprintf (temp_str, "Content-Length: %d\r\n", sb.st_size);
write_s (temp_sock, temp_str, strlen (temp_str));
strftime (temp_str, 96, "Last-Modified: %a, %d %b %Y %T GMT\r\n", gmtime (&sb.st_ctime));
write_s (temp_sock, temp_str, strlen (temp_str));
strcpy (temp_str, "\r\n"); /* ヘッダの終了 */
write_s (temp_sock, temp_str, strlen (temp_str));
#if 0
/* これじゃなんか動かん */
while (!feof (fp))
write_s (temp_sock, temp_str, fread (temp_str, sizeof (char), sizeof (temp_str), fp));
#endif
if (!strcmp (method, "GET")) {
int r1, r2 = 0;
sockmode (temp_sock, SOCK_BINARY);
for (;;) {
r1 = fread (temp_str, sizeof (char), sizeof (temp_str), fp);
if ((r2 + r1) > sb.st_size) {
r1 = sb.st_size - r2;
write_s (temp_sock, temp_str, r1);
break;
}
r2 += r1;
write_s (temp_sock, temp_str, r1);
if (feof (fp))
break;
}
}
fclose (fp);
} else {
strcpy (temp_str, "HTTP/1.0 404 Not Found\r\n");
write_s (temp_sock, temp_str, strlen (temp_str));
if (!strcmp (method, "GET")) {
strcpy (temp_str, "Content-Type: text/html\r\n");
write_s (temp_sock, temp_str, strlen (temp_str));
strcpy (temp_str, "\r\n"); /* ヘッダの終了 */
write_s (temp_sock, temp_str, strlen (temp_str));
strcpy (temp_str,
"<HTML><HEAD><TITLE>404 Not Found</TITLE></HEAD>"
"<BODY><H1>404 Not Found</H1>\r\n"
"</BODY></HTML>\r\n"
);
write_s (temp_sock, temp_str, strlen (temp_str));
} else {
strcpy (temp_str, "\r\n"); /* ヘッダの終了 */
write_s (temp_sock, temp_str, strlen (temp_str));
}
}
} else {
/* HEAD/GET 以外の処理 */
}
while (!socklen (temp_sock, 1)); /* 送信完了待ち */
shutdown (temp_sock, 0); /* 受信したデータを受け取らず,すべて廃棄する */
shutdown (temp_sock, 1); /* TCP FINを送信し,データの送出をやめる */
//shutdown (temp_sock, 2); /* connection を abortする */
close_s (temp_sock);
temp_sock = -1;
return (0);
}
int ServerTini (void)
{
if (sock80 > 0)
close_s (sock80);
if (temp_sock > 0)
close_s (temp_sock);
return (0);
}